package com.songyang.blog.controller;

import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.songyang.blog.entity.Auth;
import com.songyang.blog.entity.User;
import com.songyang.blog.redisLock.redisLock;
import com.songyang.blog.util.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;


@Slf4j
@Controller
public class IndexController extends BaseController {

    @RequestMapping({"", "/", "index"})
    public String index() throws UnsupportedEncodingException {
        //loginByCookie();//不加密的方式七天登录
        loginByCookieWithEncrypt();//加密方式的七天免登陆
//         1分页信息 2分类 3用户 4置顶  5精选 6排序
        IPage results = postService.paging(getPage(), null, null, null, "created");
        getTotalViewAndIncr(request);
        postService.initWeekRank();
        request.setAttribute("pageData", results);
        request.setAttribute("currentCategoryId", 0);
        return "index";
    }

    @RequestMapping("/search")
    public String search(String q) {
        IPage pageData = searchService.search(getPage(), q);
        request.setAttribute("q", q);
        request.setAttribute("pageData", pageData);
        return "search";
    }

    //    @ResponseBody
    @RequestMapping("/chat/getMineAndGroupData")
    public String hello() {
        return "error";
    }

    public void loginByCookieWithEncrypt() throws UnsupportedEncodingException {
        String time = "";
        String cookieValue = "";
        String key;
        if (ShiroUtils.getUser() == null || !ShiroUtils.getSubject().isAuthenticated()) {
            Cookie[] cookies = request.getCookies();
            if (cookies == null) return;//防止出现cookie为null时候报错空指针
            for (int i = 0; i < cookies.length; i++) {
                if (cookies[i].getName().equals("isLogin")) {
                    cookieValue = cookies[i].getValue();
                } else if (cookies[i].getName().equals("time")) {
                    time = cookies[i].getValue();
                }
            }
            key = (String) redisUtil.get("key:" + time);//从Redis获取解密需要的key
            if (time.isEmpty() || cookieValue.isEmpty() || key.isEmpty()) return;
//            System.out.println("得到的key："+key.getBytes().length);
            SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key.getBytes(StandardCharsets.ISO_8859_1));
            try {
                cookieValue = URLDecoder.decode(cookieValue, "utf-8");//进行utf-8解码之后的加密对象
                byte[] cookieValueBytes = cookieValue.getBytes(StandardCharsets.ISO_8859_1);//得到加密的数组
//                System.out.println("得到的字符串:" + cookieValue.length());
//                System.out.println("得到的数组："+cookieValueBytes.length);
                byte[] decrypt = aes.decrypt(cookieValueBytes);//解密之后json
//                System.out.println("解密之后的:" + new String(decrypt));
                Auth auth = JSONUtil.toBean(new String(decrypt), Auth.class);
                if (auth==null) return;
                UsernamePasswordToken token = new UsernamePasswordToken(auth.getEmail(), auth.getPassword());
                try {
                    SecurityUtils.getSubject().login(token);
                    log.info(auth.getEmail()+"登录成功");
                } catch (AuthenticationException e) {
                    if (e instanceof IncorrectCredentialsException) {
                        log.info("密码错误");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    public void loginByCookieWithoutEncrypt() {
        String cookieValue = "";
        if (ShiroUtils.getUser() == null || !ShiroUtils.getSubject().isAuthenticated()) {
            Cookie[] cookies = request.getCookies();
            for (int i = 0; i < cookies.length; i++) {
                if (cookies[i].getName().equals("isLoginUn")) {
                    cookieValue = cookies[i].getValue();
                    if (cookieValue == null || cookieValue.equals(""))
                        return;
                    break;
                }
            }
            if (cookieValue.isEmpty()) return;
            try {
                cookieValue = URLDecoder.decode(cookieValue, "UTF-8");
                User user = JSONUtil.toBean(cookieValue, User.class);
                UsernamePasswordToken token = new UsernamePasswordToken(user.getEmail(), user.getPassword());
                try {
                    SecurityUtils.getSubject().login(token);
                } catch (AuthenticationException e) {
                    if (e instanceof IncorrectCredentialsException) {
                        System.out.println("密码错误");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    private void getTotalViewAndIncr(HttpServletRequest request) {
        String keyTotal = "totalView";
        String keyNow = "totalViewNow";//两个key
        Integer totalView;//总访问量
        Integer totalViewNow;//获取今日访问量和总体访问量
        String host = request.getRemoteHost();//获取当前访问你的ip地址
        String IPKey = "host:ip" + host;
        String value = (String) redisUtil.get(IPKey);//判断一下当前Redis有没有这个人的访问你记录
        totalView = (Integer) redisUtil.get(keyTotal);//
        totalViewNow = (Integer) redisUtil.get(keyNow);//获取今日访问量和总体访问量
        //设置过期时间为600s
        if (value == null || !value.equals("1")) {//如果没有这个人记录，访问量加一，并且写入记录到Redis
            redisUtil.set(IPKey, "1");//写入记录
            redisLock redisLock = new redisLock(redisTemplate, redisUtil);
            new Thread(redisLock).start();//开启一个线程去增长访问量
        }
        redisLock redisLock = new redisLock(redisTemplate, redisUtil);
        new Thread(redisLock).start();//开启一个线程去增长访问量
//        log.info("总访问量: " + totalView);
//        log.info("今日访问量: " + totalViewNow);
        request.getSession().setAttribute("totalView", totalView);
        request.getSession().setAttribute("totalViewNow", totalViewNow);//这里用session返回给前端
    }
}
